package com.example.controller;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.example.entity.Order;
import com.example.entity.Product;
import com.example.properties.OrderProperties;
import com.example.service.OrderService;
import com.example.service.impl.OrderServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@Slf4j
//@RefreshScope
@RestController
@RequestMapping("/order")
public class OrderController {

    @Autowired
    private OrderService orderService;
    @Autowired
    private OrderServiceImpl orderServiceImpl;
    @Autowired
    private OrderProperties orderProperties;

    /**
     * nacos配置中心
     */
    @GetMapping("/getConfig")
    public String getConfig() {
        return "orderTimeout: " + orderProperties.getTimeout() + ", orderAutoConfirm: " + orderProperties.getAutoConfirm();
    }

    /**
     * @param productId
     * @param userId
     * @return
     * @RequestParam("productId") 从路径后追加?productId=001，进行参数赋值
     */
    @GetMapping("/create")
    public Order createOrder(@RequestParam("productId") Long productId, @RequestParam("userId") Long userId) {
        return orderService.createOrder(productId, userId);
    }

    /**
     * 链路流控
     * defaultValue：当没有传参时的默认值
     * required：可以不传参
     */
    @GetMapping("/seckill")
    @SentinelResource(value = "seckill-order",fallback = "seckillFallback")
    public Order seckill(@RequestParam(value = "productId",required = false) Long productId, @RequestParam(value = "userId",defaultValue = "1000") Long userId) {
        Order order = orderService.createOrder(productId, userId);
        order.setId(Long.MAX_VALUE);
        return order;
    }

    public Order seckillFallback(Long productId,Long userId, BlockException exception) {
        System.out.println("秒杀兜底回调..............");
        Order order = new Order();
        order.setId(productId);
        order.setUserId(userId);
        order.setAddress("异常信息：" + exception.getMessage());
        order.setId(Long.MAX_VALUE);
        return order;
    }
    /**
     * 关联流控
     */
    @GetMapping("/readDb")
    public String readDb(){
        return "readDb";
    }
    @GetMapping("writeDb")
    public String writeDb(){
        return "writeDb";
    }
    /**
     * 1、使用nacos的DiscoveryClient 远程调用基本实现
     *
     * @param productId
     * @return
     */
    @GetMapping("/getproduct")
    public Product getProduct(@RequestParam("productId") Long productId) {
        return orderServiceImpl.getProductFromRoute(productId);
    }

    /**
     * 2、实现负载均衡发送请求
     */
    @GetMapping("/getproduct/loadbalance")
    public Product getProductWithBalance(@RequestParam("productId") Long productId) {
        return orderServiceImpl.getProductFromRouteBalance(productId);
    }

    /**
     * 3、基于注解的负载均衡，对restTemplate添加注解@LoadBalanced
     */
    @GetMapping("/getproduct/loadbalanceAnnotation")
    public Product getProductWithBalanceAnnotation(@RequestParam("productId") Long productId) {
        return orderServiceImpl.getProductFromRouteBalanceAnnotation(productId);
    }
}

